home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_1
/
beep
/
beep.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-18
|
4KB
|
225 lines
/*
* beep.c - adds a sampled sound to DisplayBeep()
*
* Bruno Costa - 19 Feb 91 - 19 Feb 91
*
* NOTE:
* This program is VERY sensitive to compiler environment.
* Compile under Lattice 5.1 with options -r0 -y -v.
*/
/*
* TODO: add option to remove screen flash
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <graphics/gfxmacros.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include "intuition.lvo"
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define PORTNAME "beep.port"
#define INVALID (-1)
#if DETACH
long _stack = 3000;
char *_procname = "BeepHandler";
long _priority = 2;
long _BackGroundIO = 1;
extern BPTR _Backstdout;
#else
BPTR _Backstdout;
#endif
/*
* Resident Amiga libraries
*/
struct Library *IntuitionBase;
/*
* CLI Messages
*/
#define BANNER "\x1b[33mBeep 1.0\x1b[31m - \xa9 1991 by Bruno Costa\n"
#define USAGE "usage: \x1b[1mBeep\x1b[0m [-q | <soundfile>]\n"
#define REMOVING "\x1b[1mBeep:\x1b[0m handler removed.\n"
#define NOTLOAD "\x1b[1mBeep:\x1b[0m could not load desired sound.\n"
/*
* pointer to old system functions
*/
typedef void (* __asm BeepFunc) (register __a0 struct Screen *scr,
register __a6 struct Library *ibase);
static BeepFunc oldbeep;
/*
* Data shared by handler and interposed function
*/
static struct Task *handler = NULL;
ULONG beepsig = 0;
int flash = TRUE;
/*
* C routine to be interposed
*/
void __asm mybeep (register __a0 struct Screen *scr,
register __a6 struct Library *ibase)
{
Signal (handler, 1L << beepsig);
if (flash)
(*oldbeep) (scr,ibase);
}
/*
* message port
*/
static struct MsgPort myport;
void usage (void) /* dead end */
{
Write (_Backstdout, USAGE, sizeof(USAGE));
#if DETACH
Close (_Backstdout);
#endif
exit (5);
}
void main (int argc, char *argv[])
{
char *soundfile = NULL;
int removed, stay = FALSE;
struct MsgPort *port;
#if !DETACH
_Backstdout = Output();
#endif
port = FindPort (PORTNAME);
if (!port)
{
port = &myport;
stay = TRUE;
}
if (_Backstdout && argc)
{
if (stay)
Write (_Backstdout, BANNER, sizeof(BANNER));
if (argc > 2)
usage ();
else if (argc == 2)
if (argv[1][0] == '-' && argv[1][1] == 'q')
{
if (stay)
stay = FALSE;
else
{
Signal (port->mp_SigTask, 1L << port->mp_SigBit);
port = &myport;
}
Write (_Backstdout, REMOVING, sizeof(REMOVING));
}
else
soundfile = argv[1];
if (stay)
{
if (!soundfile)
usage ();
if (!load (soundfile))
{
Write (_Backstdout, NOTLOAD, sizeof(NOTLOAD));
soundfile = NULL;
}
}
#if DETACH
Close (_Backstdout);
#endif
}
if (stay && soundfile)
{
/* create port */
myport.mp_Node.ln_Name = PORTNAME;
myport.mp_Node.ln_Pri = 0;
myport.mp_Node.ln_Type = NT_MSGPORT;
myport.mp_Flags = PA_SIGNAL;
myport.mp_SigBit = AllocSignal (-1);
myport.mp_SigTask = FindTask (NULL);
AddPort (&myport);
port = &myport;
}
else
goto final;
IntuitionBase = OpenLibrary ("intuition.library", 0);
handler = FindTask (NULL);
beepsig = AllocSignal (-1);
Forbid ();
oldbeep = SetFunction (IntuitionBase, _LVODisplayBeep, mybeep);
Permit ();
removed = FALSE;
do
{
ULONG sigmask = Wait ((1L << port->mp_SigBit)|
(SIGBREAKF_CTRL_C) |
(1L << beepsig) );
if (sigmask & (1L << beepsig))
{
#if DEBUG
printf ("beeep!!!\n");
#endif
play ();
}
if (sigmask & (1L << port->mp_SigBit) || sigmask & SIGBREAKF_CTRL_C)
{
Forbid ();
{
BeepFunc pbeep = SetFunction (IntuitionBase, _LVODisplayBeep, oldbeep);
if (pbeep != mybeep)
{
/*
* Someone has interposed a handler after me. My handler can't be
* removed: otherwise the system will crash after the other handler
* removes itself.
*/
(void) SetFunction (IntuitionBase, _LVODisplayBeep, pbeep);
}
else
removed = TRUE;
}
Permit();
}
} while (!removed);
FreeSignal (beepsig);
CloseLibrary (IntuitionBase);
/* Delete port */
RemPort (port);
FreeSignal (port->mp_SigBit);
unload ();
final:
exit (0);
}